﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.ActiveRecord;
using System.ComponentModel.DataAnnotations;


namespace TES.Domain
{
    /// <summary>
    /// 系统方法（菜单）
    /// </summary>
    [ActiveRecord("SystemFunction")]
    public class SystemFunction : EntityBase
    {
        /// <summary>
        /// 系统功能名称
        /// </summary>
        [Property(NotNull = true, Length = 20)]
        [Required(ErrorMessage = "不能为空")]
        [StringLength(20, ErrorMessage = "不能超过10个字符")]
        [Display(Name = "名称")]
        public string SystemFunctionName { get; set; }

        /// <summary>
        /// 系统功能类名
        /// </summary>
        [Property(NotNull = true, Length = 200)]
        [Required(ErrorMessage = "不能为空")]
        [StringLength(200, ErrorMessage = "不能超过200个字符")]
        [Display(Name = "类名")]
        public string ClassName { get; set; }

        /// <summary>
        /// 控制器名称
        /// </summary>
        [Property(Length = 50)]
        [Required(ErrorMessage = "不能为空")]
        [StringLength(50, ErrorMessage = "不能超过50个字符")]
        [Display(Name = "控制器名称")]
        public string ControllerName { get; set; }

        /// <summary>
        /// Action名称
        /// </summary>
        [Property(Length = 200)]
        [Required(ErrorMessage = "ActionName不能为空")]
        [StringLength(50, ErrorMessage = "不能超过50个字符")]
        [Display(Name = "Action名称")]
        public string ActionName { get; set; }

        [Property]
        [Required(ErrorMessage = "请输入显示序号")]
        [Range(0,100,ErrorMessage="序号的有效范围为0-100之间的数字")]     
        [Display(Name = "序号")]
        public int Idx { get; set; }

        [Property]
        [Required(ErrorMessage="请设置是否显示选项")]
        [Display(Name = "是否显示")]
        public bool IsShow { get; set; }


        //外键要一定要先做属于关系,然后在考虑做包含关系
        //Column：当前表外键列名（功能：要与主键表的主键对应）
        //Table：属于表（主键表）的表名
        //NotNull：当前字段是否为空
        //Cascade:数据表之间的级联操作，通常使用CascadeEnum.None
        //Lazy:延迟加载/懒加载
        //返回类型：主键表对应的类名
        /// <summary>
        /// 父级功能（外键ParentID的映射）
        /// 用一对一关系实现
        /// </summary>
        [BelongsTo(Type = typeof(SystemFunction), 
            Table = "SystemFunction", 
            Column = "ParentID", 
            NotNull = false, 
            Cascade = CascadeEnum.None, 
            Lazy = FetchWhen.OnInvoke)]
        [Required(ErrorMessage = "不能为空")]
        public SystemFunction Parent { get; set; }

        /// <summary>
        /// typeof：子类的类型（外键对应的主键表所映射的类）
        /// ColumnKey:当前表要处理的外键名
        /// Cascade：数据表之间的级联操作
        /// Inverse:对象是否支持级联（当前数据发生了变化，是否不会影响到子节点，同时如果字节点发生变化，也会影响到当前节点）
        /// Lazy：延迟加载
        /// 返回类型：外键表对应的类集合
        /// 
        /// 子功能(获取当前节点的子节点)
        /// 用一对多关系实现（此关系不一定要创建，需要子节点信息的时候才创建）
        /// </summary>
        [HasMany(typeof(SystemFunction), 
            ColumnKey = "ParentID",
            Cascade = ManyRelationCascadeEnum.None, 
            Inverse = false,Lazy = false)]
        public IList<SystemFunction> Children { get; set; }

        /// <summary>
        /// typeof(与当前对象相关联的对象)，当前对象为SystemFunction，关联对象为Role
        /// Table：关联对象所对应的表名（也就是表结构中的中间表），关联对象为Role_SystemFunction，对应的表名为Role_SystemFunction
        /// ColumnKey：当前对象表（SystemFunction）中的外键列（SystemFunctionID）
        /// ColumnRef：与当前对应关联表（Role）的外键(RoleID)
        /// Cascade：数据表之间的级联操作
        /// Inverse: 补充前面的说法，如果Inverse=false，表示对应的集合数据发生变化后会反映到数据表中，如果Inverse=true，则对应
        ///          集合中的数据库发生变化后不会对数据表的数据造成影响
        /// 返回类型：与当前对应相关联的对象集合
        /// 
        /// 可以操作当前功能的角色
        /// 用多对多关系实现
        /// </summary>
        [HasAndBelongsToMany(typeof(Role), 
            Table = "Role_SystemFunction", 
            ColumnKey = "SystemFunctionID", 
            ColumnRef = "RoleID", 
            Cascade = ManyRelationCascadeEnum.All, 
            Inverse = false, 
            Lazy = false)]
        public IList<Role> Roles { get; set; }

        public bool IsChecked
        {
            get;
            set;
        }
    }
}
